package com.zm.tools.generatebackcode.core;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import static com.zm.tools.util.core.generatecode.common.PackageNameUtil.getPackage;

/**
 * @author zoum
 * @create 2018/10/25 17:14
 */
public class GenerateFacadeCode {

    private final static Logger LOGGER = LoggerFactory.getLogger(GenerateFacadeCode.class);
    private final static String MODEL_NAME = "facade";

    public static void generate(String baseFilePath, String tableName, String companyName, String appName) throws IOException{
        String pakage = getPackage(companyName, appName, MODEL_NAME);
        generateWrite(baseFilePath, tableName, appName, MODEL_NAME, pakage);
        generateRead(baseFilePath, tableName, appName, MODEL_NAME, pakage);
        generateDubboXML(baseFilePath, tableName, appName, MODEL_NAME);
        GeneratePomCode.generate(baseFilePath, tableName, companyName, appName, 1, MODEL_NAME);
    }

    private static void generateDubboXML(String baseFilePath, String tableName, String appName, String modelName) throws IOException{
        generateBaseDubboXML(baseFilePath, tableName, appName, modelName);
        generateWriteDubboXML(baseFilePath, tableName, appName, modelName);
        generateReadDubboXML(baseFilePath, tableName, appName, modelName);
    }

    private static void generateWrite(String baseFilePath, String tableName, String appName, String modelName, String pakage) throws IOException{
        LOGGER.info("generateFacade4Write start for " + tableName);
        String readOrWrite = "write";
        String parentPath = baseFilePath + "\\" + appName + "\\"+ appName + "-" + modelName + "\\src\\main\\java\\" + pakage.replace(".","\\") + "\\"  + readOrWrite;
        File parentFile  = new File(parentPath);
        if (!parentFile.exists()){
            parentFile.mkdirs();
        }
        String className = tableName + StringUtils.capitalize(readOrWrite) + "Facade.java";
        File classFile = new File(parentFile.getPath(), className);
        if (classFile.exists()){
            classFile.delete();
        }
        classFile.createNewFile();
        String dtoName = tableName + "DTO";
        String dtoInstanceName = String.valueOf(dtoName.charAt(0)).toLowerCase() + dtoName.substring(1);
        String serviceName = tableName + StringUtils.capitalize(readOrWrite) + "Service";
        String serviceInstanceName = String.valueOf(serviceName.charAt(0)).toLowerCase() + serviceName.substring(1);
        FileWriter fw = new FileWriter(classFile);
        StringBuilder sb = new StringBuilder();
        sb.append("package "+ pakage + "." + readOrWrite + ";\n\n")
                .append("import com.rongzhijia.jiedianqian.basic."+ (appName.length()>1 ? appName.split("-")[1] : appName.split("-")[0]) +".model.dto." + tableName.toLowerCase() + "." + dtoName + ";\n")
                .append("import com.rongzhijia.jiedianqian.basic."+ (appName.length()>1 ? appName.split("-")[1] : appName.split("-")[0]) +".api."+ readOrWrite +"." + serviceName + ";\n\n")
                .append("import org.springframework.beans.factory.annotation.Autowired;\n")
                .append("import org.springframework.stereotype.Component;\n\n")
                .append("import java.util.Date;\n\n")
                .append("@Component\n")
                .append("public class " + className.split("\\.")[0] + " {\n\n")
                .append("   @Autowired\n")
                .append("   private " + serviceName + " " + serviceInstanceName + ";\n\n")
                .append("   public int add( " + dtoName + " " + dtoInstanceName + "){\n")
                .append("       Date date = new Date();\n")
                .append("       "+ dtoInstanceName + ".setCreateTime(date);\n")
                .append("       "+ dtoInstanceName + ".setUpdateTime(date);\n")
                .append("       return " + serviceInstanceName + ".insert"+ tableName + "Service(" + dtoInstanceName + ");\n")
                .append("   }\n\n")
                .append("   public int update( " + dtoName + " " + dtoInstanceName + "){\n")
                .append("       Date date = new Date();\n")
                .append("       "+ dtoInstanceName + ".setUpdateTime(date);\n")
                .append("       return " + serviceInstanceName + ".update"+ tableName + "Service(" + dtoInstanceName + ");\n")
                .append("   }\n")
                .append("   public int delete( " + dtoName + " " + dtoInstanceName + "){\n")
                .append("       return " + serviceInstanceName + ".delete"+ tableName + "Service(" + dtoInstanceName + ");\n")
                .append("   }\n")
                .append("}");
        fw.write(sb.toString());
        fw.flush();
        fw.close();
        LOGGER.info("generateFacade4Write end for " + tableName);
    }

    private static void generateRead(String baseFilePath, String tableName, String appName, String modelName, String pakage) throws IOException{
        LOGGER.info("generateFacade4Read start for " + tableName);
        String readOrWrite = "read";
        String parentPath = baseFilePath + "\\" + appName + "\\"+ appName + "-" + modelName + "\\src\\main\\java\\" + pakage.replace(".","\\") + "\\"  + readOrWrite;
        File parentFile  = new File(parentPath);
        if (!parentFile.exists()){
            parentFile.mkdirs();
        }
        String className = tableName + StringUtils.capitalize(readOrWrite) + "Facade.java";
        File classFile = new File(parentFile.getPath(), className);
        if (classFile.exists()){
            classFile.delete();
        }
        classFile.createNewFile();
        String dtoName = tableName + "DTO";
        String dtoInstanceName = String.valueOf(dtoName.charAt(0)).toLowerCase() + dtoName.substring(1);
        String serviceName = tableName + StringUtils.capitalize(readOrWrite) + "Service";
        String serviceInstanceName = String.valueOf(serviceName.charAt(0)).toLowerCase() + serviceName.substring(1);
        FileWriter fw = new FileWriter(classFile);
        StringBuilder sb = new StringBuilder();
        sb.append("package "+ pakage + "."  + readOrWrite + ";\n\n")
                .append("import com.rongzhijia.jdq.core.common.PageResult;\n")
                .append("import com.rongzhijia.jdq.core.orm.Pagination;\n")
                .append("import com.rongzhijia.jiedianqian.basic."+ (appName.length()>1 ? appName.split("-")[1] : appName.split("-")[0]) +".model.dto." + tableName.toLowerCase() + "." + dtoName + ";\n")
                .append("import com.rongzhijia.jiedianqian.basic."+ (appName.length()>1 ? appName.split("-")[1] : appName.split("-")[0]) +".api."+ readOrWrite +"." + serviceName + ";\n\n")
                .append("import org.springframework.beans.factory.annotation.Autowired;\n")
                .append("import org.springframework.stereotype.Component;\n\n")
                .append("import java.util.List;\n\n")
                .append("@Component\n")
                .append("public class " + className.split("\\.")[0] + " {\n\n")
                .append("   @Autowired\n")
                .append("   private " + serviceName + " " + serviceInstanceName + ";\n\n")
                .append("   public "+ dtoName + " get"+ tableName + "Service(" + dtoName + " " + dtoInstanceName + "){\n")
                .append("       return " + serviceInstanceName + ".get"+ tableName + "Service(" + dtoInstanceName + ");\n")
                .append("   }\n\n")
                .append("   public List<" + dtoName + "> query" + tableName + "Service(" + dtoName + " " + dtoInstanceName + "){\n")
                .append("       return " + serviceInstanceName + ".query"+ tableName + "Service(" + dtoInstanceName + ");\n")
                .append("   }\n\n")
                .append("   public List<" + dtoName + "> query" + tableName + "Service(" + dtoName + " " + dtoInstanceName + ", Pagination pagination){\n")
                .append("       PageResult<" + dtoName + "> " + dtoInstanceName + "Page = this.select" + tableName + "PageService(" + dtoInstanceName + ", pagination);\n")
                .append("       if("+ dtoInstanceName + "Page != null && "+ dtoInstanceName +"Page.getList() != null){\n")
                .append("           return "+ dtoInstanceName +"Page.getList();\n")
                .append("       }\n")
                .append("       return null;\n")
                .append("   }\n\n")
                .append("   public PageResult<" + dtoName + "> select" + tableName + "PageService(" + dtoName + " " + dtoInstanceName + ", Pagination pagination){\n")
                .append("       if (pagination != null){\n")
                .append("            pagination.setLimitStart((pagination.getPageNo()-1)*pagination.getPageSize());\n")
                .append("       }\n")
                .append("       return " + serviceInstanceName + ".select"+ tableName + "PageService(" + dtoInstanceName + ", pagination);\n")
                .append("   }\n\n")
                .append("}");
        fw.write(sb.toString());
        fw.flush();
        fw.close();
        LOGGER.info("generateFacade4Read start for " + tableName);
    }

    private static void generateWriteDubboXML(String baseFilePath, String tableName, String appName, String modelName) throws IOException{
        LOGGER.info("generateFacade4Write start for " + tableName);
        String readOrWrite = "write";
        String parentPath = baseFilePath + "\\" + appName + "\\"+ appName + "-" + modelName +"\\src\\main\\resources\\dubbo";
        File parentFile  = new File(parentPath);
        if (!parentFile.exists()){
            parentFile.mkdirs();
        }
        String className = "dubbo-consumer-" + tableName + "-" + readOrWrite + ".xml";
        File classFile = new File(parentFile.getPath(), className);
        if (classFile.exists()){
            classFile.delete();
        }
        classFile.createNewFile();
        String serviceName = tableName + StringUtils.capitalize(readOrWrite) + "Service";
        String serviceInstanceName = String.valueOf(serviceName.charAt(0)).toLowerCase() + serviceName.substring(1);
        FileWriter fw = new FileWriter(classFile);
        StringBuilder sb = new StringBuilder();
        sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
                .append("<beans xmlns=\"http://www.springframework.org/schema/beans\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n")
                .append("   xmlns:dubbo=\"http://code.alibabatech.com/schema/dubbo\"\n")
                .append("   xsi:schemaLocation=\"http://www.springframework.org/schema/beans\n")
                .append("       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd\n")
                .append("       http://code.alibabatech.com/schema/dubbo\n")
                .append("       http://code.alibabatech.com/schema/dubbo/dubbo.xsd\"\n")
                .append("       default-autowire=\"byName\" default-lazy-init=\"false\">\n")
                .append("   <dubbo:reference interface=\"com.rongzhijia.jiedianqian.basic."+ (appName.length()>1 ? appName.split("-")[1] : appName.split("-")[0]) +".api."+ readOrWrite +"."+ serviceName +"\" id=\""+ serviceInstanceName +"\" check=\"false\"/>\n")
                .append("</beans>\n")
        ;
        fw.write(sb.toString());
        fw.flush();
        fw.close();
        LOGGER.info("generateFacade4Write end for " + tableName);
    }

    private static void generateBaseDubboXML(String baseFilePath, String tableName, String appName, String modelName) throws IOException{
        LOGGER.info("generateBaseDubboXML start for " + tableName);
        String parentPath = baseFilePath + "\\" + appName + "\\"+ appName + "-" + modelName +"\\src\\main\\resources\\dubbo";
        File parentFile  = new File(parentPath);
        if (!parentFile.exists()){
            parentFile.mkdirs();
        }
        String className = "dubbo-consumer.xml";
        File classFile = new File(parentFile.getPath(), className);
        if (classFile.exists()){
            classFile.delete();
        }
        classFile.createNewFile();
        FileWriter fw = new FileWriter(classFile);
        StringBuilder sb = new StringBuilder();
        sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
                .append("<beans xmlns=\"http://www.springframework.org/schema/beans\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n")
                .append("   xmlns:dubbo=\"http://code.alibabatech.com/schema/dubbo\"\n")
                .append("   xsi:schemaLocation=\"http://www.springframework.org/schema/beans\n")
                .append("       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd\n")
                .append("       http://code.alibabatech.com/schema/dubbo\n")
                .append("       http://code.alibabatech.com/schema/dubbo/dubbo.xsd\"\n")
                .append(
                        "       default-autowire=\"byName\" default-lazy-init=\"false\">\n" +
                        "       <!-- 消费方应用名，用于计算依赖关系，不是匹配条件，不要与提供方一样 -->\n" +
                        "       <dubbo:application name=\"back-member\"/>\n" +
                        "       <!-- 使用zookeeper注册中心暴露服务地址 -->\n" +
                        "       <!-- 注册中心地址 -->\n" +
                        "       <dubbo:registry protocol=\"zookeeper\" address=\"${cluster.serverList}\"/>\n" +
                        "       <import resource=\"dubbo-consumer-*.xml\" />\n" +
                        "       <dubbo:monitor protocol=\"registry\"/>\n")
                .append("</beans>\n")
        ;
        fw.write(sb.toString());
        fw.flush();
        fw.close();
        LOGGER.info("generateBaseDubboXML end for " + tableName);
    }

    private static void generateReadDubboXML(String baseFilePath, String tableName, String appName, String modelName) throws IOException{
        LOGGER.info("generateFacade4Write start for " + tableName);
        String readOrWrite = "read";
        String parentPath = baseFilePath + "\\" + appName + "\\"+ appName + "-" + modelName +"\\src\\main\\resources\\dubbo";
        File parentFile  = new File(parentPath);
        if (!parentFile.exists()){
            parentFile.mkdirs();
        }
        String className = "dubbo-consumer-" + tableName + "-" + readOrWrite + ".xml";
        File classFile = new File(parentFile.getPath(), className);
        if (classFile.exists()){
            classFile.delete();
        }
        classFile.createNewFile();
        String serviceName = tableName + StringUtils.capitalize(readOrWrite) + "Service";
        String serviceInstanceName = String.valueOf(serviceName.charAt(0)).toLowerCase() + serviceName.substring(1);
        FileWriter fw = new FileWriter(classFile);
        StringBuilder sb = new StringBuilder();
        sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
                .append("<beans xmlns=\"http://www.springframework.org/schema/beans\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n")
                .append("   xmlns:dubbo=\"http://code.alibabatech.com/schema/dubbo\"\n")
                .append("   xsi:schemaLocation=\"http://www.springframework.org/schema/beans\n")
                .append("       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd\n")
                .append("       http://code.alibabatech.com/schema/dubbo\n")
                .append("       http://code.alibabatech.com/schema/dubbo/dubbo.xsd\"\n")
                .append("       default-autowire=\"byName\" default-lazy-init=\"false\">\n")
                .append("   <dubbo:reference interface=\"com.rongzhijia.jiedianqian.basic."
                        + (appName.length()>1 ? appName.split("-")[1] : appName.split("-")[0]) +
                        ".api." + readOrWrite +"."+ serviceName +"\" id=\""+ serviceInstanceName +"\" check=\"false\"/>\n")
                .append("</beans>\n")
        ;
        fw.write(sb.toString());
        fw.flush();
        fw.close();
        LOGGER.info("generateFacade4Write end for " + tableName);
    }
}
